package com.ding.commander;

import com.ding.common.*;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Logger;

public class CommunicationAccepter {


    private static Logger logger = Logger.getLogger("mynat");

    private CommanderChannelHolder commanderHolder;

    private CPool pool;

    private ServerSocket communicationListener;

    private int communicationListenerPort;

    private String password;

    void setCommunicationListenerPort(int communicationListenerPort) {
        this.communicationListenerPort = communicationListenerPort;
    }

    void setCommanderHolder(CommanderChannelHolder commanderHolder) {
        this.commanderHolder = commanderHolder;
    }

    void setPassword(String password) {
        this.password = password;
    }

    void setPool(CPool pool) {
        this.pool = pool;
    }


    void start() throws IOException {
        this.communicationListener = new ServerSocket(this.communicationListenerPort);
        Threads.exe(() -> {
            while (true) {
                Socket socket;
                try {
                    socket = communicationListener.accept();
                } catch (IOException e) {
                    break;
                }
                newConnect(socket);
            }
        });
        logger.info("通道监听|开始");
    }


    private void newConnect(Socket socket) {

        //交给新线程进行处理
        Threads.exe(() -> {

            MessageChannel holder = new MessageChannel(socket);

            //等待读取一条消息
            Waiter.TaskHolder taskHolder = Waiter.setTimeout(() -> {
                try {
                    socket.close();
                    logger.info("长时间未读取到消息,服务端主动关闭流");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }, 2000);

            Message message;
            message = holder.readMsg();
            taskHolder.clear();

            if (message == null) {
                holder.close();
                return;
            }

            String type = message.getType();

            String password = message.getPassword();

            String id = message.getId();

            //设置id
            holder.setId(id);

            if (!password.equals(CommunicationAccepter.this.password)) {
                holder.sendMsg(new Message().type(Constant.CLOSE).msg("密码错误"));
                holder.close();
                logger.info("指令通信|连接时密码错误|已回绝");
                return;
            }

            switch (type) {
                case Constant.NEW_STREAM:

                    System.out.println("新的流连接通信");

                    if (message.getIntroducerId() == null) {
                        System.out.println("没有引荐id,终止");
                        break;
                    }

                    //设置引荐者id
                    holder.setIntroducerId(message.getIntroducerId());

                    if (pool.addOne(holder)) {

                        System.out.println("添加成功");

                        holder.sendMsg(new Message().type(Constant.SUCCESS));
                        logger.info("流通信|建立");
                    } else {
                        System.out.println("添加失败");

                        holder.sendMsg(new Message().type(Constant.CLOSE).msg("超出容量池上限"));
                    }

                    break;
                case Constant.NEW_COMMAND:
                    CommanderChannel commanderChannel = new CommanderChannel(holder.getSocket());
                    commanderChannel.setId(holder.getId());
                    commanderHolder.set(commanderChannel);
                    break;
                default:
                    holder.close();
                    logger.info("未知通信|已关闭");
                    break;
            }

        });
    }

    void stop() {

        try {
            communicationListener.close();
            logger.info("通道监听|关闭");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
